/* eslint-disable */
	/**
	 * @fileoverview 百度地图的测距工具类，对外开放。
	 * 允许用户在地图上点击完成距离的测量。
	 * 使用者可以自定义测距线段的相关样式，例如线宽、颜色、测距结果所用的单位制等等。
	 * 主入口类是<a href="symbols/BMapLib.DistanceTool.html">DistanceTool</a>，
	 * 基于Baidu Map API 1.2。
	 *
	 * @author Baidu Map Api Group
	 * @version 1.2
	 */
	
	/**
	 * @namespace BMap的所有library类均放在BMapLib命名空间下
	 */
   var BMapLib = (window.BMapLib = BMapLib || {});
	
   (function() {
       /**
        * 声明baidu包
        */
       var baidu = baidu || {guid: '$BAIDU$'};
       (function() {
           // 一些页面级别唯一的属性，需要挂载在window[baidu.guid]上
           window[baidu.guid] = {};
 
     /**
      * 将源对象的所有属性拷贝到目标对象中
      * @name baidu.extend
      * @function
      * @grammar baidu.extend(target, source)
      * @param {Object} target 目标对象
      * @param {Object} source 源对象
      * @returns {Object} 目标对象
      */
     baidu.extend = function(target, source) {
         for (var p in source) {
             if (source.hasOwnProperty(p)) {
                 target[p] = source[p];
             }
         }
         return target;
     };
 
     /**
      * @ignore
      * @namespace
      * @baidu.lang 对语言层面的封装，包括类型判断、模块扩展、继承基类以及对象自定义事件的支持。
      * @property guid 对象的唯一标识
      */
     baidu.lang = baidu.lang || {};
 
     /**
      * 返回一个当前页面的唯一标识字符串。
      * @function
      * @grammar baidu.lang.guid()
      * @returns {String} 当前页面的唯一标识字符串
      */
     baidu.lang.guid = function() {
         return 'TANGRAM__' + (window[baidu.guid]._counter++).toString(36);
     };
 
     window[baidu.guid]._counter = window[baidu.guid]._counter || 1;
 
     /**
      * 所有类的实例的容器
      * key为每个实例的guid
      */
     window[baidu.guid]._instances = window[baidu.guid]._instances || {};
 
     /**
      * Tangram继承机制提供的一个基类，用户可以通过继承baidu.lang.Class来获取它的属性及方法。
      * @function
      * @name baidu.lang.Class
      * @grammar baidu.lang.Class(guid)
      * @param {string} guid	对象的唯一标识
      * @meta standard
      * @remark baidu.lang.Class和它的子类的实例均包含一个全局唯一的标识guid。
      * guid是在构造函数中生成的，因此，继承自baidu.lang.Class的类应该直接或者间接调用它的构造函数。<br>
      * baidu.lang.Class的构造函数中产生guid的方式可以保证guid的唯一性，及每个实例都有一个全局唯一的guid。
      */
     baidu.lang.Class = function(guid) {
         this.guid = guid || baidu.lang.guid();
         window[baidu.guid]._instances[this.guid] = this;
     };
 
     window[baidu.guid]._instances = window[baidu.guid]._instances || {};
 
     /**
      * 判断目标参数是否string类型或String对象
      * @name baidu.lang.isString
      * @function
      * @grammar baidu.lang.isString(source)
      * @param {Any} source 目标参数
      * @shortcut isString
      * @meta standard
      *
      * @returns {boolean} 类型判断结果
      */
     baidu.lang.isString = function(source) {
         return '[object String]' == Object.prototype.toString.call(source);
     };
 
     /**
      * 判断目标参数是否为function或Function实例
      * @name baidu.lang.isFunction
      * @function
      * @grammar baidu.lang.isFunction(source)
      * @param {Any} source 目标参数
      * @returns {boolean} 类型判断结果
      */
     baidu.lang.isFunction = function(source) {
         return '[object Function]' == Object.prototype.toString.call(source);
     };
 
     /**
      * 重载了默认的toString方法，使得返回信息更加准确一些。
      * @return {string} 对象的String表示形式
      */
     baidu.lang.Class.prototype.toString = function() {
         return '[object ' + (this._className || 'Object') + ']';
     };
 
     /**
      * 释放对象所持有的资源，主要是自定义事件。
      * @name dispose
      * @grammar obj.dispose()
      */
     baidu.lang.Class.prototype.dispose = function() {
         delete window[baidu.guid]._instances[this.guid];
         for (var property in this) {
             if (!baidu.lang.isFunction(this[property])) {
                 delete this[property];
             }
         }
         this.disposed = true;
     };
 
     /**
      * 自定义的事件对象。
      * @function
      * @name baidu.lang.Event
      * @grammar baidu.lang.Event(type[, target])
      * @param {string} type	 事件类型名称。为了方便区分事件和一个普通的方法，事件类型名称必须以"on"(小写)开头。
      * @param {Object} [target]触发事件的对象
      * @meta standard
      * @remark 引入该模块，会自动为Class引入3个事件扩展方法：addEventListener、removeEventListener和dispatchEvent。
      * @see baidu.lang.Class
      */
     baidu.lang.Event = function(type, target) {
         this.type = type;
         this.returnValue = true;
         this.target = target || null;
         this.currentTarget = null;
     };
 
     /**
      * 注册对象的事件监听器。引入baidu.lang.Event后，Class的子类实例才会获得该方法。
      * @grammar obj.addEventListener(type, handler[, key])
      * @param 	{string}   type         自定义事件的名称
      * @param 	{Function} handler      自定义事件被触发时应该调用的回调函数
      * @param 	{string}   [key]		为事件监听函数指定的名称，可在移除时使用。如果不提供，方法会默认为它生成一个全局唯一的key。
      * @remark 	事件类型区分大小写。如果自定义事件名称不是以小写"on"开头，该方法会给它加上"on"再进行判断，即"click"和"onclick"会被认为是同一种事件。
      */
     baidu.lang.Class.prototype.addEventListener = function(type, handler, key) {
         if (!baidu.lang.isFunction(handler)) {
             return;
         }
         !this.__listeners && (this.__listeners = {});
         var t = this.__listeners,
             id;
         if (typeof key == 'string' && key) {
             if (/[^\w\-]/.test(key)) {
                 throw 'nonstandard key:' + key;
             } else {
                 handler.hashCode = key;
                 id = key;
             }
         }
         type.indexOf('on') != 0 && (type = 'on' + type);
         typeof t[type] != 'object' && (t[type] = {});
         id = id || baidu.lang.guid();
         handler.hashCode = id;
         t[type][id] = handler;
     };
 
     /**
      * 移除对象的事件监听器。引入baidu.lang.Event后，Class的子类实例才会获得该方法。
      * @grammar obj.removeEventListener(type, handler)
      * @param {string}   type     事件类型
      * @param {Function|string} handler  要移除的事件监听函数或者监听函数的key
      * @remark 	如果第二个参数handler没有被绑定到对应的自定义事件中，什么也不做。
      */
     baidu.lang.Class.prototype.removeEventListener = function(type, handler) {
         if (baidu.lang.isFunction(handler)) {
             handler = handler.hashCode;
         } else if (!baidu.lang.isString(handler)) {
             return;
         }
         !this.__listeners && (this.__listeners = {});
         type.indexOf('on') != 0 && (type = 'on' + type);
         var t = this.__listeners;
         if (!t[type]) {
             return;
         }
         t[type][handler] && delete t[type][handler];
     };
 
     /**
      * 派发自定义事件，使得绑定到自定义事件上面的函数都会被执行。引入baidu.lang.Event后，Class的子类实例才会获得该方法。
      * @grammar obj.dispatchEvent(event, options)
      * @param {baidu.lang.Event|String} event 	Event对象，或事件名称(1.1.1起支持)
      * @param {Object} options 扩展参数,所含属性键值会扩展到Event对象上(1.2起支持)
      * @remark 处理会调用通过addEventListenr绑定的自定义事件回调函数之外，还会调用直接绑定到对象上面的自定义事件。
      * 例如：<br>
      * myobj.onMyEvent = function(){}<br>
      * myobj.addEventListener("onMyEvent", function(){});
      */
     baidu.lang.Class.prototype.dispatchEvent = function(event, options) {
         if (baidu.lang.isString(event)) {
             event = new baidu.lang.Event(event);
         }
         !this.__listeners && (this.__listeners = {});
         options = options || {};
         for (var i in options) {
             event[i] = options[i];
         }
         var i,
             t = this.__listeners,
             p = event.type;
         event.target = event.target || this;
         event.currentTarget = this;
         p.indexOf('on') != 0 && (p = 'on' + p);
         baidu.lang.isFunction(this[p]) && this[p].apply(this, arguments);
         if (typeof t[p] == 'object') {
             for (i in t[p]) {
                 t[p][i].apply(this, arguments);
             }
         }
         return event.returnValue;
     };
 
     /**
      * 为类型构造器建立继承关系
      * @name baidu.lang.inherits
      * @function
      * @grammar baidu.lang.inherits(subClass, superClass[, className])
      * @param {Function} subClass 子类构造器
      * @param {Function} superClass 父类构造器
      * @param {string} className 类名标识
      * @remark 使subClass继承superClass的prototype，
      * 因此subClass的实例能够使用superClass的prototype中定义的所有属性和方法。<br>
      * 这个函数实际上是建立了subClass和superClass的原型链集成，并对subClass进行了constructor修正。<br>
      * <strong>注意：如果要继承构造函数，需要在subClass里面call一下，具体见下面的demo例子</strong>
      * @shortcut inherits
      * @meta standard
      * @see baidu.lang.Class
      */
     baidu.lang.inherits = function(subClass, superClass, className) {
         var key,
             proto,
             selfProps = subClass.prototype,
             clazz = new Function();
         clazz.prototype = superClass.prototype;
         proto = subClass.prototype = new clazz();
         for (key in selfProps) {
             proto[key] = selfProps[key];
         }
         subClass.prototype.constructor = subClass;
         subClass.superClass = superClass.prototype;
 
         if ('string' == typeof className) {
             proto._className = className;
         }
     };
 
     /**
      * @ignore
      * @namespace baidu.dom 操作dom的方法。
      */
     baidu.dom = baidu.dom || {};
 
     /**
      * 从文档中获取指定的DOM元素
      *
      * @param {string|HTMLElement} id 元素的id或DOM元素
      * @meta standard
      * @return {HTMLElement} DOM元素，如果不存在，返回null，如果参数不合法，直接返回参数
      */
     baidu._g = baidu.dom._g = function(id) {
         if (baidu.lang.isString(id)) {
             return document.getElementById(id);
         }
         return id;
     };
 
     /**
      * 从文档中获取指定的DOM元素
      * @name baidu.dom.g
      * @function
      * @grammar baidu.dom.g(id)
      * @param {string|HTMLElement} id 元素的id或DOM元素
      * @meta standard
      *
      * @returns {HTMLElement|null} 获取的元素，查找不到时返回null,如果参数不合法，直接返回参数
      */
     baidu.g = baidu.dom.g = function(id) {
         if ('string' == typeof id || id instanceof String) {
             return document.getElementById(id);
         } else if (id && id.nodeName && (id.nodeType == 1 || id.nodeType == 9)) {
             return id;
         }
         return null;
     };
 
     /**
      * 在目标元素的指定位置插入HTML代码
      * @name baidu.dom.insertHTML
      * @function
      * @grammar baidu.dom.insertHTML(element, position, html)
      * @param {HTMLElement|string} element 目标元素或目标元素的id
      * @param {string} position 插入html的位置信息，取值为beforeBegin,afterBegin,beforeEnd,afterEnd
      * @param {string} html 要插入的html
      * @remark
      *
      * 对于position参数，大小写不敏感<br>
      * 参数的意思：beforeBegin&lt;span&gt;afterBegin   this is span! beforeEnd&lt;/span&gt; afterEnd <br />
      * 此外，如果使用本函数插入带有script标签的HTML字符串，script标签对应的脚本将不会被执行。
      *
      * @shortcut insertHTML
      * @meta standard
      *
      * @returns {HTMLElement} 目标元素
      */
     baidu.insertHTML = baidu.dom.insertHTML = function(element, position, html) {
         element = baidu.dom.g(element);
         var range, begin;
 
         if (element.insertAdjacentHTML) {
             element.insertAdjacentHTML(position, html);
         } else {
             // 这里不做"undefined" != typeof(HTMLElement) && !window.opera判断，其它浏览器将出错？！
             // 但是其实做了判断，其它浏览器下等于这个函数就不能执行了
             range = element.ownerDocument.createRange();
             // FF下range的位置设置错误可能导致创建出来的fragment在插入dom树之后html结构乱掉
             // 改用range.insertNode来插入html, by wenyuxiang @ 2010-12-14.
             position = position.toUpperCase();
             if (position == 'AFTERBEGIN' || position == 'BEFOREEND') {
                 range.selectNodeContents(element);
                 range.collapse(position == 'AFTERBEGIN');
             } else {
                 begin = position == 'BEFOREBEGIN';
                 range[begin ? 'setStartBefore' : 'setEndAfter'](element);
                 range.collapse(begin);
             }
             range.insertNode(range.createContextualFragment(html));
         }
         return element;
     };
 
     /**
      * 为目标元素添加className
      * @name baidu.dom.addClass
      * @function
      * @grammar baidu.dom.addClass(element, className)
      * @param {HTMLElement|string} element 目标元素或目标元素的id
      * @param {string} className 要添加的className，允许同时添加多个class，中间使用空白符分隔
      * @remark
      * 使用者应保证提供的className合法性，不应包含不合法字符，className合法字符参考：http://www.w3.org/TR/CSS2/syndata.html。
      * @shortcut addClass
      * @meta standard
      *
      * @returns {HTMLElement} 目标元素
      */
     baidu.ac = baidu.dom.addClass = function(element, className) {
         element = baidu.dom.g(element);
         var classArray = className.split(/\s+/),
             result = element.className,
             classMatch = ' ' + result + ' ',
             i = 0,
             l = classArray.length;
 
         for (; i < l; i++) {
             if (classMatch.indexOf(' ' + classArray[i] + ' ') < 0) {
                 result += (result ? ' ' : '') + classArray[i];
             }
         }
 
         element.className = result;
         return element;
     };
 
     /**
      * @ignore
      * @namespace baidu.event 屏蔽浏览器差异性的事件封装。
      * @property target 	事件的触发元素
      * @property pageX 		鼠标事件的鼠标x坐标
      * @property pageY 		鼠标事件的鼠标y坐标
      * @property keyCode 	键盘事件的键值
      */
     baidu.event = baidu.event || {};
 
     /**
      * 事件监听器的存储表
      * @private
      * @meta standard
      */
     baidu.event._listeners = baidu.event._listeners || [];
 
     /**
      * 为目标元素添加事件监听器
      * @name baidu.event.on
      * @function
      * @grammar baidu.event.on(element, type, listener)
      * @param {HTMLElement|string|window} element 目标元素或目标元素id
      * @param {string} type 事件类型
      * @param {Function} listener 需要添加的监听器
      * @remark
      *  1. 不支持跨浏览器的鼠标滚轮事件监听器添加<br>
      *  2. 改方法不为监听器灌入事件对象，以防止跨iframe事件挂载的事件对象获取失败
      * @shortcut on
      * @meta standard
      * @see baidu.event.un
      *
      * @returns {HTMLElement|window} 目标元素
      */
     baidu.on = baidu.event.on = function(element, type, listener) {
         type = type.replace(/^on/i, '');
         element = baidu._g(element);
         var realListener = function(ev) {
                 // 1. 这里不支持EventArgument,  原因是跨frame的事件挂载
                 // 2. element是为了修正this
                 listener.call(element, ev);
             },
             lis = baidu.event._listeners,
             filter = baidu.event._eventFilter,
             afterFilter,
             realType = type;
         type = type.toLowerCase();
         // filter过滤
         if (filter && filter[type]) {
             afterFilter = filter[type](element, type, realListener);
             realType = afterFilter.type;
             realListener = afterFilter.listener;
         }
         // 事件监听器挂载
         if (element.addEventListener) {
             element.addEventListener(realType, realListener, false);
         } else if (element.attachEvent) {
             element.attachEvent('on' + realType, realListener);
         }
 
         // 将监听器存储到数组中
         lis[lis.length] = [element, type, listener, realListener, realType];
         return element;
     };
 
     /**
      * 为目标元素移除事件监听器
      * @name baidu.event.un
      * @function
      * @grammar baidu.event.un(element, type, listener)
      * @param {HTMLElement|string|window} element 目标元素或目标元素id
      * @param {string} type 事件类型
      * @param {Function} listener 需要移除的监听器
      * @shortcut un
      * @meta standard
      *
      * @returns {HTMLElement|window} 目标元素
      */
     baidu.un = baidu.event.un = function(element, type, listener) {
         element = baidu._g(element);
         type = type.replace(/^on/i, '').toLowerCase();
 
         var lis = baidu.event._listeners,
             len = lis.length,
             isRemoveAll = !listener,
             item,
             realType,
             realListener;
 
         //如果将listener的结构改成json
         //可以节省掉这个循环，优化性能
         //但是由于un的使用频率并不高，同时在listener不多的时候
         //遍历数组的性能消耗不会对代码产生影响
         //暂不考虑此优化
         while (len--) {
             item = lis[len];
 
             // listener存在时，移除element的所有以listener监听的type类型事件
             // listener不存在时，移除element的所有type类型事件
             if (item[1] === type && item[0] === element && (isRemoveAll || item[2] === listener)) {
                 realType = item[4];
                 realListener = item[3];
                 if (element.removeEventListener) {
                     element.removeEventListener(realType, realListener, false);
                 } else if (element.detachEvent) {
                     element.detachEvent('on' + realType, realListener);
                 }
                 lis.splice(len, 1);
             }
         }
         return element;
     };
 
     /**
      * 阻止事件的默认行为
      * @name baidu.event.preventDefault
      * @function
      * @grammar baidu.event.preventDefault(event)
      * @param {Event} event 事件对象
      * @meta standard
      */
     baidu.preventDefault = baidu.event.preventDefault = function(event) {
         if (event.preventDefault) {
             event.preventDefault();
         } else {
             event.returnValue = false;
         }
     };
 })();
 
//  /**
//   * @exports DistanceTool as BMapLib.DistanceTool
//   */
 var DistanceTool =
     /**
      * DistanceTool类的构造函数
      * @class 距离测算类，实现测距效果的<b>入口</b>。
      * 实例化该类后，即可调用该类提供的open
      * 方法开启测距状态。
      *
      * @constructor
      * @param {Map} map Baidu map的实例对象
      * @param {Json Object} opts 可选的输入参数，非必填项。可输入选项包括：<br />
      * {"<b>followText</b>" : {String} 测距过程中，提示框文字,
      * <br />"<b>unit</b>" : {String} 测距结果所用的单位制，可接受的属性为"metric"表示米制和"us"表示美国传统单位,
      * <br />"<b>lineColor</b>" : {String} 折线颜色,
      * <br />"<b>lineStroke</b>" : {Number} 折线宽度,
      * <br />"<b>opacity</b>" : {Number} 透明度,
      * <br />"<b>lineStyle</b>" : {String} 折线的样式，只可设置solid和dashed,
      * <br />"<b>secIcon</b>" : {BMap.Icon} 转折点的Icon,
      * <br />"<b>closeIcon</b>" : {BMap.Icon} 关闭按钮的Icon,
      * <br />"<b>cursor</b>" : {String} 跟随的鼠标样式}
      *
      * @example <b>参考示例：</b><br />
      * var map = new BMap.Map("container");<br />map.centerAndZoom(new BMap.Point(116.404, 39.915), 15);<br />var myDistanceToolObject = new BMapLib.DistanceTool(map, {lineStroke : 2});
      */
     (BMapLib.DistanceTool = function(map, opts) {
         if (!map) {
             return;
         }
 
         // 以下部分是添加的代码
         // 解决进入详情页后返回概览页，测距功能点击不生效问题 
         if (OperationMask._maskElement) {
             OperationMask._maskElement = null;
         }
         //以上部分是添加的代码
 
         /**
          * map对象
          * @private
          * @type {Map}
          */
         this._map = map;
 
         opts = opts || {};
         /**
          * _opts是默认参数赋值。
          * 下面通过用户输入的opts，对默认参数赋值
          * @private
          * @type {Json}
          */
         this._opts = baidu.extend(
             baidu.extend(this._opts || {}, {
                 /**
                  * 测距提示
                  * @private
                  * @type {String}
                  */
                 tips: '测距',
 
                 /**
                  * 测距过程中，提示框文字
                  * @private
                  * @type {String}
                  */
                 followText: '单击确定地点，双击结束',
 
                 /**
                  * 测距结果所用的单位制，可接受的属性为"metric"表示米制和"us"表示美国传统单位
                  * @private
                  * @type {String}
                  */
                 unit: 'metric',
 
                 /**
                  * 折线颜色
                  * @private
                  * @type {String}
                  */
                 lineColor: '#ff6319',
 
                 /**
                  * 折线线宽
                  * @private
                  * @type {Number}
                  */
                 lineStroke: 2,
 
                 /**
                  * 折线透明度
                  * @private
                  * @type {Number}
                  */
                 opacity: 0.8,
 
                 /**
                  * 折线样式
                  * @private
                  * @type {String}
                  */
                 lineStyle: 'solid',
 
                 /**
                  * 跟随鼠标样式
                  * @private
                  * @type {String}
                  */
                 cursor: 'http://api.map.baidu.com/images/ruler.cur',
 
                 /**
                  * 转折点的ICON样式
                  * @private
                  * @type {BMap.Icon}
                  */
                 secIcon: null,
 
                 /**
                  * 转折点的ICON样式
                  * @private
                  * @type {BMap.Icon}
                  */
                 closeIcon: null
             }),
             opts
         );
 
         /**
          * 跟随的title覆盖物
          * @private
          * @type {BMap.Label}
          */
         this._followTitle = null;
 
         /**
          * 折线包含所有点的数组
          * @private
          * @type {Array}
          */
         this._points = [];
 
         /**
          * 折线所包含的所有path数组
          * @private
          * @type {Array}
          */
         this._paths = [];
 
         /**
          * 折线结点图片数组
          * @private
          * @type {Array}
          */
         this._dots = [];
 
         /**
          * 折线测距包含所有线段的距离
          * @private
          * @type {Array}
          */
         this._segDistance = [];
 
         /**
          * 覆盖物的数组
          * @private
          * @type {Array}
          */
         this._overlays = [];
 
         /**
          * 是否在调用map.clearOverlays清除画线需要建立的相关overlay元素
          * @private
          * @type {Boolean}
          */
         (this._enableMassClear = true),
             /**
              * 单位制，存储语言包中定义的单位名称
              * @private
              * @type {Json}
              */
             (this._units = {
                 // metric 表示米制
                 metric: {
                     /**
                      * 米制的名称
                      * @type {String}
                      */
                     name: 'metric',
 
                     /**
                      * 和米制的换算关系
                      * @type {Number}
                      */
                     conv: 1,
 
                     /**
                      * 米制单位下两个单位制之间的换算关系
                      * @type {Number}
                      */
                     incon: 1000,
 
                     /**
                      * 米制单位下较小单位
                      * @type {String}
                      */
                     u1: '米',
 
                     /**
                      * 米制单位下较大单位
                      * @type {String}
                      */
                     u2: '公里'
                 },
                 // us 表示美国传统单位，各参数意义同上metric
                 us: {
                     name: 'us',
                     conv: 3.2808,
                     incon: 5279.856,
                     u1: '英尺',
                     u2: '英里'
                 }
             });
 
         /**
          * 是否已经开启了测距状态
          * @private
          * @type {Boolean}
          */
         this._isOpen = false;
 
         /**
          * 未点击任何一点时，鼠标移动时的跟随提示文字
          * @private
          * @type {String}
          */
         this._startFollowText = '单击确定起点';
 
         /**
          * 地图移动的计时器
          * @private
          * @type {Object}
          */
         this._movingTimerId = null;
 
         /**
          * 测距需要添加的CSS样式
          * @private
          * @type {Json}
          */
         this._styles = {
             BMapLib_diso:
                 'height:17px;width:5px;position:absolute;background:url(http://api.map.baidu.com/images/dis_box_01.gif) no-repeat left top',
             BMapLib_disi:
                 'color:#7a7a7a;position:absolute;left:5px;padding:0 4px 1px 0;line-height:17px;background:url(http://api.map.baidu.com/images/dis_box_01.gif) no-repeat right top',
             BMapLib_disBoxDis: 'color:#ff6319;font-weight:bold'
         };
 
         if (this._opts.lineStroke <= 0) {
             this._opts.lineStroke = 2;
         }
         if (this._opts.opacity > 1) {
             this._opts.opacity = 1;
         } else if (this._opts.opacity < 0) {
             this._opts.opacity = 0;
         }
         if (this._opts.lineStyle != 'solid' && this._opts.lineStyle != 'dashed') {
             this._opts.lineStyle = 'solid';
         }
         if (!this._units[this._opts.unit]) {
             this._opts.unit = 'metric';
         }
 
         this.text = '测距';
     });
 
 // 通过baidu.lang下的inherits方法，让DistanceTool继承baidu.lang.Class
 baidu.lang.inherits(DistanceTool, baidu.lang.Class, 'DistanceTool');
 
 /**
  * 地图区域的移动事件绑定
  * @return 无返回值
  */
 DistanceTool.prototype._bind = function() {
     // 设置鼠标样式
     this._setCursor(this._opts.cursor);
     var me = this;
     // 在装载地图的页面元素上，绑定鼠标移动事件
     baidu.on(this._map.getContainer(), 'mousemove', function(e) {
         if (!me._isOpen) {
             return;
         }
         if (!me._followTitle) {
             return;
         }
         e = window.event || e;
         var t = e.target || e.srcElement;
         // 如果触发该事件的页面元素不是遮盖效果层，则返回，无操作
         if (t != OperationMask.getDom(me._map)) {
             me._followTitle.hide();
             return;
         }
         if (!me._mapMoving) {
             me._followTitle.show();
         }
         // 设置鼠标移动过程中，跟随的文字提示框的位置
         var pt = OperationMask.getDrawPoint(e, true);
         me._followTitle.setPosition(pt);
     });
     // 创建鼠标跟随的文字提示框
     if (this._startFollowText) {
         var t = (this._followTitle = new BMap.Label(this._startFollowText, {offset: new BMap.Size(14, 16)}));
         this._followTitle.setStyles({color: '#333', borderColor: '#ff0103'});
     }
 };
 
 /**
  * 开启地图的测距状态
  * @return {Boolean}，开启测距状态成功，返回true；否则返回false。
  *
  * @example <b>参考示例：</b><br />
  * myDistanceToolObject.open();
  */
 DistanceTool.prototype.open = function() {
     // 判断测距状态是否已经开启
     if (this._isOpen == true) {
         return true;
     }
     // 已有其他地图上的鼠标操作工具开启
     if (!!BMapLib._toolInUse) {
         return;
     }
     this._isOpen = true;
     BMapLib._toolInUse = true;
 
     // 判断是否是否在移动过程中
     if (this._mapMoving) {
         delete this._mapMoving;
     }
 
     var me = this;
     // 增加鼠标在地图区域移动的事件
     // 通过binded参数，避免多次绑定
     if (!this._binded) {
         this._binded = true;
         // 绑定控件项事件
         this._bind();
         // 地图的移动过程中，需要隐藏相关的提示框
         this._map.addEventListener('moving', function() {
             me._hideCurrent();
         });
     }
 
     // 将文字提示框作为BMap.Label元素，提交给Map Api进行管理
     if (this._followTitle) {
         this._map.addOverlay(this._followTitle);
         this._followTitle.hide();
     }
 
     /**
      * 测距过程中，点击地图时，触发的操作
      * @ignore
      * @param {Object} e event对象
      */
     var distClick = function(e) {
         var map = me._map;
         if (!me._isOpen) {
             return;
         }
         // 通过event对象，计算得出点击位置的物理坐标，poi为一个BMap.Point对象
         e = window.event || e;
         var poi = OperationMask.getDrawPoint(e, true);
         // 验证计算得出的该点的位置合理性
         if (!me._isPointValid(poi)) {
             return;
         }
         // 记录当前点的屏幕位置
         me._bind.initX = e.pageX || e.clientX || 0;
         me._bind.initY = e.pageY || e.clientY || 0;
 
         // 这个if循环内的计算是，判断当前这个点，与存储内的最后一个点的距离，
         // 如果距离过小，比如小于5，可以认为是用户的误点，可以忽略掉
         if (me._points.length > 0) {
             var lstPx = map.pointToPixel(me._points[me._points.length - 1]);
             var thisPx = map.pointToPixel(poi);
             var dis = Math.sqrt(Math.pow(lstPx.x - thisPx.x, 2) + Math.pow(lstPx.y - thisPx.y, 2));
             if (dis < 5) {
                 return;
             }
         }
         // offsetX 与 layerX，offsetY 与 layerY位置调整
         // 解决safrai浏览器下鼠标位置与点击位置不一致问题
         me._bind.x = e.offsetX || e.layerX || 0;
         me._bind.y = e.offsetY || e.layerY || 0;
         me._points.push(poi);
         // 添加测距结点
         me._addSecPoint(poi);
 
         // 调整跟踪鼠标的标签
         if (me._paths.length == 0) {
             me._formatTitle(1, me._opts.followText, me._getTotalDistance());
         }
 
         // 修改确定线的颜色
         if (me._paths.length > 0) {
             me._paths[me._paths.length - 1].show();
             me._paths[me._paths.length - 1].setStrokeOpacity(me._opts.opacity);
         }
 
         var path = new BMap.Polyline([poi, poi], {enableMassClear: me._enableMassClear});
         me._map.addOverlay(path);
         me._paths.push(path);
         me._overlays.push(path);
 
         // 测距模式下线样式固定
         path.setStrokeWeight(me._opts.lineStroke);
         path.setStrokeColor(me._opts.lineColor);
         path.setStrokeOpacity(me._opts.opacity / 2);
         path.setStrokeStyle(me._opts.lineStyle);
 
         // 如果地图正在移动则隐藏掉
         if (me._mapMoving) {
             path.hide();
         }
 
         if (me._points.length > 1) {
             var siblingPath = me._paths[me._points.length - 2];
             siblingPath.setPositionAt(1, poi);
         }
 
         // 生成节点旁边的距离显示框
         var disText = '';
         if (me._points.length > 1) {
             // 非起点的节点，显示当前的距离
             var segDis = me._setSegDistance(me._points[me._points.length - 2], me._points[me._points.length - 1]);
             var meters = me._getTotalDistance();
             disText = me._formatDisStr(meters);
         } else {
             disText = '起点';
         }
         var disLabel = new BMap.Label(disText, {
             offset: new BMap.Size(10, -5),
             enableMassClear: me._enableMassClear
         });
         disLabel.setStyles({color: '#333', borderColor: '#ff0103'});
         me._map.addOverlay(disLabel);
         me._formatSegLabel(disLabel, disText);
         me._overlays.push(disLabel);
         poi.disLabel = disLabel;
         disLabel.setPosition(poi);
 
         /**
          * 测距过程中，每次点击底图添加节点时，派发事件的接口
          * @name DistanceTool#onaddpoint
          * @event
          * @param {Event Object} e 回调函数会返回event参数，包括以下返回值：
          * <br />{"<b>point</b> : {BMap.Point} 最新添加上的节点BMap.Point对象,
          * <br />"<b>pixel</b>：{BMap.pixel} 最新添加上的节点BMap.Pixel对象,
          * <br />"<b>index</b>：{Number} 最新添加的节点的索引,
          * <br />"<b>distance</b>：{Number} 截止最新添加的节点的总距离}
          *
          * @example <b>参考示例：</b><br />
          * myDistanceToolObject.addEventListener("addpoint", function(e) {  alert(e.distance);  });
          */
 
         // 生成名为onaddpoint的baidu.lang.Event对象
         // 并给该event对象添加上point、pixel、index和distance等属性字段
         // 然后在此刻，将绑定在onaddpoint上事件，全部赋予event参数，然后派发出去
         var event = new baidu.lang.Event('onaddpoint');
         event.point = poi;
         event.pixel = me._map.pointToPixel(poi);
         event.index = me._points.length - 1;
         event.distance = me._getTotalDistance().toFixed(0);
         me.dispatchEvent(event);
     };
 
     /**
      * 测距过程中，鼠标在地图上移动时，触发的操作
      * @ignore
      * @param {Object} e event对象
      */
     var distMove = function(e) {
         if (!me._isOpen) {
             return;
         }
         // 通过判断数组me._paths的长度，判断当前是否已经有测量节点
         // 也就是，如果没有节点，则还没有开始测量
         if (me._paths.length > 0) {
             // 通过event参数，计算当前点的位置
             e = window.event || e;
             var curX = e.pageX || e.clientX || 0;
             var curY = e.pageY || e.clientY || 0;
             if (typeof me._bind.initX == 'undefined') {
                 // offsetX 与 layerX，offsetY 与 layerY位置调整
                 // 解决safrai浏览器下鼠标位置与点击位置不一致问题 
                 me._bind.x = e.offsetX || e.layerX || 0;
                 me._bind.y = e.offsetY || e.layerY || 0;
                 me._bind.initX = curX;
                 me._bind.initY = curY;
             }
             var x = me._bind.x + curX - me._bind.initX;
             var y = me._bind.y + curY - me._bind.initY;
 
             // 修改最后一条折线的终点位置，使之随着鼠标移动画线
             var path = me._paths[me._paths.length - 1];
             var poi = me._map.pixelToPoint(new BMap.Pixel(x, y));
             path.setPositionAt(1, poi);
 
             if (!me._mapMoving) {
                 path.show();
             }
             var dx = 0;
             var dy = 0;
             // 计算当前鼠标位置，是否靠近边界、或者已经出了边界
             // 如果在边界位置，则需要向对应的方向移动地图，来进行测量
             // 每次移动的距离，设定为8
             if (x < 10) {
                 dx = 8;
             } else if (x > me._map.getSize().width - 10) {
                 dx = -8;
             }
             if (y < 10) {
                 dy = 8;
             } else if (y > me._map.getSize().height - 10) {
                 dy = -8;
             }
             // 如果dx和dy都等于0，表明不需要移动地图
             if (dx != 0 || dy != 0) {
                 // 此时需要向一个方向，平移地图
                 if (!distMove._movingTimerId) {
                     me._mapMoving = true;
                     me._map.panBy(dx, dy, {noAnimation: true});
                     me._movingTimerId = distMove._movingTimerId = setInterval(function() {
                         me._map.panBy(dx, dy, {noAnimation: true});
                     }, 30);
                     // 地图移动过程中，隐藏线段和标签
                     path.hide();
                     me._followTitle && me._followTitle.hide();
                 }
             } else {
                 if (distMove._movingTimerId) {
                     // 此时用户不在需要移动地图来测量，可以清除计时器
                     clearInterval(distMove._movingTimerId);
                     delete distMove._movingTimerId;
                     delete me._movingTimerId;
 
                     // 显示跟随提示框，并修改线路位置
                     var lstP = me._paths[me._paths.length - 1];
                     var poiN = me._map.pixelToPoint(new BMap.Pixel(x, y));
                     if (!lstP) {
                         return;
                     }
                     lstP.setPositionAt(1, poiN);
                     lstP.show();
                     if (me._followTitle) {
                         me._followTitle.setPosition(poiN);
                         me._followTitle.show();
                     }
                     me._bind.i = 0;
                     me._bind.j = 0;
                     delete me._mapMoving;
                 }
             }
             // 实时更新文字提示框中的距离
             if (me._followTitle) {
                 var td = me._getTotalDistance();
                 var dis = me._map.getDistance(me._points[me._points.length - 1], poi);
                 me._updateInstDis(me._followTitle, td + dis);
             }
         } else {
             // 此时用户还没有开始测量，只是鼠标随便在地图上移动
             if (me._followTitle) {
                 me._followTitle.show();
                 e = window.event || e;
                 var t = e.target || e.srcElement;
                 if (t != OperationMask.getDom()) {
                     me._followTitle.hide();
                 }
             }
         }
     };
 
     /**
      * 测距要结束时，双击地图，触发的操作
      * @ignore
      * @param {Object} e event对象
      */
     var distDblclick = function(e) {
         if (!me._isOpen) {
             return;
         }
         // 结束时，删除绑定的事件
         baidu.un(OperationMask.getDom(me._map), 'click', distClick);
         baidu.un(document, 'mousemove', distMove);
         baidu.un(OperationMask.getDom(me._map), 'dblclick', distDblclick);
         baidu.un(document, 'keydown', distKeyDown);
         baidu.un(OperationMask.getDom(me._map), 'mouseup', distMouseUp);
 
         // 调用close()关闭测距状态
         setTimeout(function() {
             me.close();
         }, 50);
     };
 
     /**
      * 测距时的键盘操作
      * @ignore
      * @param {Object} e event对象
      */
     var distKeyDown = function(e) {
         e = window.event || e;
         if (e.keyCode == 27) {
             // [ESC]退出本次测距
             me._clearCurData();
             setTimeout(function() {
                 me.close();
             }, 50);
         }
     };
 
     /**
      * 测距过程中，鼠标弹起时，触发的操作
      * @ignore
      * @param {Object} e event对象
      */
     var distMouseUp = function(e) {
         e = window.event || e;
         var ieVersion = 0;
         if (/msie (\d+\.\d)/i.test(navigator.userAgent)) {
             ieVersion = document.documentMode || +RegExp['\x241'];
         }
         if ((ieVersion && e.button != 1) || e.button == 2) {
             me.close();
         }
     };
 
     // 初始化存储数据
     me._initData();
 
     // 调整title的内容
     this._formatTitle();
 
     // 创建透明覆盖层，并设置鼠标样式
     OperationMask.show(this._map);
     this._setCursor(this._opts.cursor);
 
     // 绑定全部事件
     baidu.on(OperationMask.getDom(this._map), 'click', distClick);
     baidu.on(document, 'mousemove', distMove);
     baidu.on(OperationMask.getDom(this._map), 'dblclick', distDblclick);
     baidu.on(document, 'keydown', distKeyDown);
     baidu.on(OperationMask.getDom(this._map), 'mouseup', distMouseUp);
 
     // 将绑定的事件、和对应的绑定对象，记录在数组中
     this.bindFunc = [
         {elem: OperationMask.getDom(this._map), type: 'click', func: distClick},
         {elem: OperationMask.getDom(this._map), type: 'dblclick', func: distDblclick},
         {elem: document, type: 'mousemove', func: distMove},
         {elem: document, type: 'keydown', func: distKeyDown},
         {elem: OperationMask.getDom(this._map), type: 'mouseup', func: distMouseUp}
     ];
     return true;
 };
 
 /**
  * 画线结束时，派发drawend事件
  * @return 无返回值
  */
 DistanceTool.prototype._dispatchLastEvent = function() {
     /**
      * 测距时，每次双击底图结束当前测距折线时，派发事件的接口
      * @name DistanceTool#ondrawend
      * @event
      * @param {Event Object} e 回调函数会返回event参数，包括以下返回值：
      * <br />{"<b>points</b> : {BMap.Point} 所有测量时，打下的节点BMap.Point对象,
      * <br />"<b>overlays</b>：{Array} 所有测量时，生成的线段BMap.Overlay对象,
      * <br />"<b>distance</b>：{Number} 测量解释时的最终距离}
      *
      * @example <b>参考示例：</b><br />
      * myDistanceToolObject.addEventListener("drawend", function(e) {  alert(e.distance);  });
      */
 
     // 生成名为ondrawend的baidu.lang.Event对象
     // 并给该event对象添加上points、overlays和distance等属性字段
     // 然后在此刻，将绑定在ondrawend上事件，全部赋予event参数，然后派发出去
     var event = new baidu.lang.Event('ondrawend');
     event.points = this._points ? this._points.slice(0) : [];
     event.overlays = this._paths ? this._paths.slice(0, this._paths.length - 1) : [];
     event.distance = this._getTotalDistance().toFixed(0);
     this.dispatchEvent(event);
 };
 
 /**
  * 关闭测距状态
  * @return 无返回值
  *
  * @example <b>参考示例：</b><br />
  * myDistanceToolObject.close();
  */
 DistanceTool.prototype.close = function() {
     if (this._isOpen == false) {
         return;
     }
     this._isOpen = false;
     BMapLib._toolInUse = false;
 
     if (this._mapMoving) {
         delete this._mapMoving;
     }
     var me = this;
     me._dispatchLastEvent();
     if (me._points.length < 2) {
         // 不是有效绘制，清除所有内容
         me._clearCurData();
     } else {
         me._paths[me._paths.length - 1].remove();
         me._paths[me._paths.length - 1] = null;
         me._paths.length = me._paths.length - 1;
         // 移除最近一次标记
         var pt = me._points[me._points.length - 1];
         if (pt.disLabel) {
             pt.disLabel.remove();
         }
         me._processLastOp();
     }
     OperationMask.hide();
 
     // 删除绑定的事件
     for (var i = 0, l = this.bindFunc.length; i < l; i++) {
         baidu.un(this.bindFunc[i].elem, this.bindFunc[i].type, this.bindFunc[i].func);
     }
 
     // 停止地图移动
     if (me._movingTimerId) {
         clearInterval(me._movingTimerId);
         me._movingTimerId = null;
     }
 
     if (this._followTitle) {
         this._followTitle.hide();
     }
 };
 
 /**
  * 清除本次测距的暂存数据
  * @return 无返回值
  */
 DistanceTool.prototype._clearCurData = function() {
     for (var i = 0, l = this._points.length; i < l; i++) {
         if (this._points[i].disLabel) {
             this._points[i].disLabel.remove();
         }
     }
     for (var i = 0, l = this._paths.length; i < l; i++) {
         this._paths[i].remove();
     }
     for (var i = 0, l = this._dots.length; i < l; i++) {
         this._dots[i].remove();
     }
     this._initData();
 };
 
 /**
  * 初始化存储数组
  * @return 无返回值
  */
 DistanceTool.prototype._initData = function() {
     // 初始化point数组
     this._points.length = 0;
     // 初始化path数组
     this._paths.length = 0;
     // 初始化分段距离数组
     this._segDistance.length = 0;
     // 初始化结点图像数组
     this._dots.length = 0;
 };
 
 /**
  * 计算两点之间距离并存放在分段距离数组中
  * @param {Point}
  * @param {Point}
  * @return {Number} 两个地理点之间的距离
  */
 DistanceTool.prototype._setSegDistance = function(pt0, pt1) {
     if (!pt0 || !pt1) {
         return;
     }
     var dis = this._map.getDistance(pt0, pt1);
     this._segDistance.push(dis);
     return dis;
 };
 
 /**
  * 获得总距离
  * @return {Number} 总距离
  */
 DistanceTool.prototype._getTotalDistance = function() {
     var totalDis = 0;
     for (var i = 0, l = this._segDistance.length; i < l; i++) {
         totalDis += this._segDistance[i];
     }
     return totalDis;
 };
 
 /**
  * 将米制单位的数值换算成为目标单位下的数值
  * @type {Number} 需要转换的数值
  * @type {String} 字符串描述的目标单位，
  * "metric" 表示米制单位，
  * "us" 表示美国传统单位制
  * @return {Number} 转换后的数值
  */
 DistanceTool.prototype._convertUnit = function(num, unit) {
     unit = unit || 'metric';
     if (this._units[unit]) {
         return num * this._units[unit].conv;
     }
     return num;
 };
 
 /**
  * 添加测距结点
  * @param {BMap.Point} 节点
  * @return 无返回值
  */
 DistanceTool.prototype._addSecPoint = function(pt) {
     var ico = this._opts.secIcon
         ? this._opts.secIcon
         : new BMap.Icon('http://api.map.baidu.com/images/mapctrls.png', new BMap.Size(11, 11), {
               imageOffset: new BMap.Size(-26, -313)
           });
     var secPt = new BMap.Marker(pt, {
         icon: ico,
         clickable: false,
         baseZIndex: 3500000,
         zIndexFixed: true,
         enableMassClear: this._enableMassClear
     });
     this._map.addOverlay(secPt);
     this._dots.push(secPt);
 };
 
 /**
  * 格式化距离字符串
  * @param {Number} 距离
  * @return {String} 格式化的字符串
  */
 DistanceTool.prototype._formatDisStr = function(distance) {
     var u = this._opts.unit;
     var unit = this._units[u].u1;
     var dis = this._convertUnit(distance, u);
 
     if (dis > this._units[u].incon) {
         dis = dis / this._units[u].incon;
         unit = this._units[u].u2;
         dis = dis.toFixed(1);
     } else {
         dis = dis.toFixed(0);
     }
     return dis + unit;
 };
 
 /**
  * 设置鼠标样式
  * @param {String} cursor 鼠标样式
  * @return 没有返回值
  */
 DistanceTool.prototype._setCursor = function(cursor) {
     // 由于webkit内核浏览器下，cursor设置后默认不会居中，所以需要对偏移值进行设置
     var csr = /webkit/.test(navigator.userAgent.toLowerCase())
         ? 'url(' + this._opts.cursor + ') 3 6, crosshair'
         : 'url(' + this._opts.cursor + '), crosshair';
     OperationMask._setCursor(csr);
 };
 
 /**
  * 获取鼠标样式
  * @return {String} 跟随的鼠标样式
  */
 DistanceTool.prototype._getCursor = function() {
     return this._opts.cursor;
 };
 
 /**
  * 调整分段距离样式
  * @param {BMap.Label} label 提示框的Label
  * @param {String} 需要填入的文字
  * @return 没有返回值
  */
 DistanceTool.prototype._formatSegLabel = function(label, text) {
     label.setStyle({border: 'none', padding: '0'});
     label.setContent(
         "<span style='" +
             this._styles.BMapLib_diso +
             "'><span style='" +
             this._styles.BMapLib_disi +
             "'>" +
             text +
             '</span></span>'
     );
 };
 
 /**
  * 处理最后一次操作，当用户双击或测距被强行退出时调用
  * @return 没有返回值
  */
 DistanceTool.prototype._processLastOp = function() {
     var me = this;
     // 删除上次移动临时数据
     delete me._bind.x;
     delete me._bind.y;
     delete me._bind.initX;
     delete me._bind.initY;
     // 验证路径
     if (me._paths.length > me._points.length - 1) {
         var l = me._paths.length - 1;
         me._paths[l].remove();
         me._paths[l] = null;
         me._paths.length = l;
     }
     // 保存本次测距对象
     var disObj = {};
     disObj.points = me._points.slice(0);
     disObj.paths = me._paths.slice(0);
     disObj.dots = me._dots.slice(0);
     disObj.segDis = me._segDistance.slice(0);
     // 判断总距离和按钮位置
     var lstPx = me._map.pointToPixel(disObj.points[disObj.points.length - 1]);
     var prePx = me._map.pointToPixel(disObj.points[disObj.points.length - 2]);
     var btnOffset = [0, 0];
     var disOffset = [0, 0];
     if (lstPx.y - prePx.y >= 0) {
         // 距离位于下端
         disOffset = [-5, 11];
     } else {
         // 距离位于上端
         disOffset = [-5, -35];
     }
     if (lstPx.x - prePx.x >= 0) {
         // 按钮位于右侧
         btnOffset = [14, 0];
     } else {
         // 按钮位于左侧
         btnOffset = [-14, 0];
     }
     // 显示总距离
     var pt = disObj.points[disObj.points.length - 1];
     pt.disLabel = new BMap.Label('', {offset: new BMap.Size(-15, -40), enableMassClear: me._enableMassClear});
     pt.disLabel.setStyles({color: '#333', borderColor: '#ff0103'});
     me._map.addOverlay(pt.disLabel);
     pt.disLabel.setOffset(new BMap.Size(disOffset[0], disOffset[1]));
     pt.disLabel.setPosition(pt);
     me._formatTitle(2, '', '', pt.disLabel);
     // 添加关闭按钮
     var bico = this._opts.closeIcon
         ? this._opts.closeIcon
         : new BMap.Icon('http://api.map.baidu.com/images/mapctrls.gif', new BMap.Size(12, 12), {
               imageOffset: new BMap.Size(0, -14)
           });
     disObj.closeBtn = new BMap.Marker(disObj.points[disObj.points.length - 1], {
         icon: bico,
         offset: new BMap.Size(btnOffset[0], btnOffset[1]),
         baseZIndex: 3600000,
         enableMassClear: me._enableMassClear
     });
     me._map.addOverlay(disObj.closeBtn);
     disObj.closeBtn.setTitle('清除本次测距');
     // 点击关闭按钮，绑定关闭按钮事件
     disObj.closeBtn.addEventListener('click', function(e) {
         // 关闭本次测距，清除相关存储和变量
         for (var i = 0, l = disObj.points.length; i < l; i++) {
             disObj.points[i].disLabel.remove();
             disObj.points[i].disLabel = null;
         }
         for (var i = 0, l = disObj.paths.length; i < l; i++) {
             disObj.paths[i].remove();
             disObj.paths[i] = null;
         }
         for (var i = 0, l = disObj.dots.length; i < l; i++) {
             disObj.dots[i].remove();
             disObj.dots[i] = null;
         }
         disObj.closeBtn.remove();
         disObj.closeBtn = null;
         stopBubble(e);
 
         /**
          * @ignore
          * 测距结束后，点击线段上最后一个节点旁的关闭按钮时，派发事件的接口
          * @name DistanceTool#onremovepolyline
          * @event
          * @param {Event Object} e 回调函数会返回event参数
          *
          * @example <b>参考示例：</b><br />
          * myDistanceToolObject.addEventListener("removepolyline", function(e) {  alert(e.type);  });
          */
 
         // 生成名为onremovepolyline的baidu.lang.Event对象
         // 然后在此刻，将绑定在onremovepolyline上事件，全部赋予event参数，然后派发出去
         var event = new baidu.lang.Event('onremovepolyline');
         me.dispatchEvent(event);
     });
     me._initData();
 };
 
 /**
  * 生成测距过程中的文字提示框
  * @param {String} type
  * @param {String} text
  * @param {String} distance
  * @param {Label} label
  * @return 无返回值
  */
 DistanceTool.prototype._formatTitle = function(type, text, distance, label) {
     var title = label || this._followTitle;
     if (!title) {
         return;
     }
     title.setStyle({lineHeight: '16px', zIndex: '85', padding: '3px 5px'});
     var t = this._startFollowText || '';
     var htmls = [];
     if (type == 1) {
         // 测距过程中的提示
         title.setOffset(0, 25);
         var u = this._opts.unit;
         var unit = this._units[u].u1;
         var dis = this._convertUnit(distance, u);
         if (dis > this._units[u].incon) {
             dis = dis / this._units[u].incon;
             unit = this._units[u].u2;
             dis = dis.toFixed(1);
         } else {
             dis = dis.toFixed(0);
         }
         htmls.push(
             "<span>总长：<span style='" +
                 this._styles.BMapLib_disBoxDis +
                 "'>" +
                 dis +
                 '</span>' +
                 unit +
                 '</span><br />'
         );
         htmls.push("<span style='color:#7a7a7a'>" + text + '</span>');
     } else if (type == 2) {
         // 结束时的总距离展示
         var u = this._opts.unit;
         var unit = this._units[u].u1;
         var dis = this._convertUnit(this._getTotalDistance(), u);
         if (dis > this._units[u].incon) {
             dis = dis / this._units[u].incon;
             unit = this._units[u].u2;
             dis = dis.toFixed(1);
         } else {
             dis = dis.toFixed(0);
         }
         htmls.push("总长：<span style='" + this._styles.BMapLib_disBoxDis + "'>" + dis + '</span>' + unit);
     } else {
         title.setOffset(0, 25);
         htmls.push(t);
     }
     title.setContent(htmls.join(''));
 };
 
 /**
  * 更新label的距离
  * @param HTMLElement label的DOM元素
  * @param Number 距离
  */
 DistanceTool.prototype._updateInstDis = function(label, dis) {
     // 换算距离
     var u = this._opts.unit;
     var unit = this._units[u].u1;
     if (dis > this._units[u].incon) {
         dis = dis / this._units[u].incon;
         unit = this._units[u].u2;
         dis = dis.toFixed(1);
     } else {
         dis = dis.toFixed(0);
     }
     // 修改Label的内容
     if (label) {
         var htmls = [];
         htmls.push(
             "<span>总长：<span style='" +
                 this._styles.BMapLib_disBoxDis +
                 "'>" +
                 dis +
                 '</span>' +
                 unit +
                 '</span><br />'
         );
         htmls.push("<span style='color:#7a7a7a'>" + this._opts.followText + '</span>');
         label.setContent(htmls.join(''));
     }
 };
 
 /**
  * 隐藏相关的线段和提示框文字
  * @return 无返回值
  */
 DistanceTool.prototype._hideCurrent = function() {
     if (!this._isOpen) {
         return;
     }
     if (this._paths.length > 0) {
         var p = this._paths[this._paths.length - 1];
         p.hide();
     }
     this._followTitle && this._followTitle.hide();
 };
 
 /**
  * 验证传入点的位置合理性
  * @param {BMap.Point} pt 需要被验证的point点
  * @return 无返回值
  */
 DistanceTool.prototype._isPointValid = function(pt) {
     if (!pt) {
         return false;
     }
     var mapBounds = this._map.getBounds();
     var sw = mapBounds.getSouthWest(),
         ne = mapBounds.getNorthEast();
     if (pt.lng < sw.lng || pt.lng > ne.lng || pt.lat < sw.lat || pt.lat > ne.lat) {
         return false;
     }
     return true;
 };
 
 /**
  * OperationMask，透明覆盖层，在地图上进行鼠标绘制操作时使用，
  * 闭包，对外不暴露
  */
 var OperationMask = {
     /**
      * map对象
      * @type {Map}
      */
     _map: null,
 
     /**
      * HTML字符串
      * @type {String}
      */
     _html:
         "<div style='background:transparent url(http://api.map.baidu.com/images/blank.gif);position:absolute;left:0;top:0;width:100%;height:100%;z-index:1000' unselectable='on'></div>",
 
     /**
      * html元素
      * @type {HTMLElement}
      */
     _maskElement: null,
 
     /**
      * 鼠标指针
      * @type {String}
      */
     _cursor: 'default',
 
     /**
      * 操作层是否在使用中
      * @type {Boolean}
      */
     _inUse: false,
 
     /**
      * 透明覆盖层的显示
      *
      * @param {Map} map map对象
      * @return 无返回值
      */
     show: function(map) {
         if (!this._map) {
             this._map = map;
         }
         this._inUse = true;
         if (!this._maskElement) {
             this._createMask(map);
         }
         this._maskElement.style.display = 'block';
     },
 
     /**
      * 创建覆盖层
      *
      * @param {Map} map map对象
      * @return 无返回值
      */
     _createMask: function(map) {
         this._map = map;
         if (!this._map) {
             return;
         }
         baidu.insertHTML(this._map.getContainer(), 'beforeEnd', this._html);
         var elem = (this._maskElement = this._map.getContainer().lastChild);
 
         var stopAndPrevent = function(e) {
             stopBubble(e);
             return baidu.preventDefault(e);
         };
         baidu.on(elem, 'mouseup', function(e) {
             if (e.button == 2) {
                 stopAndPrevent(e);
             }
         });
         baidu.on(elem, 'contextmenu', stopAndPrevent);
         elem.style.display = 'none';
     },
 
     /**
      * 获取当前绘制点的地理坐标
      *
      * @param {Event} e e对象
      * @param {Boolean} n 是否向上查到相对于地图container元素的坐标位置
      * @return Point对象的位置信息
      */
     getDrawPoint: function(e, n) {
         e = window.event || e;
         // offsetX 与 layerX，offsetY 与 layerY位置调整
         // 解决safrai浏览器下鼠标位置与点击位置不一致问题 
         var x = e.offsetX || e.layerX || 0;
         var y = e.offsetY || e.layerY || 0;
         var t = e.target || e.srcElement;
         if (t != OperationMask.getDom(this._map) && n == true) {
             while (t && t != this._map.getContainer()) {
                 if (
                     !(
                         t.clientWidth == 0 &&
                         t.clientHeight == 0 &&
                         t.offsetParent &&
                         t.offsetParent.nodeName.toLowerCase() == 'td'
                     )
                 ) {
                     x += t.offsetLeft;
                     y += t.offsetTop;
                 }
                 t = t.offsetParent;
             }
         }
 
         if (t != OperationMask.getDom(this._map) && t != this._map.getContainer()) {
             return;
         }
         if (typeof x === 'undefined' || typeof y === 'undefined') {
             return;
         }
         if (isNaN(x) || isNaN(y)) {
             return;
         }
         return this._map.pixelToPoint(new BMap.Pixel(x, y));
     },
 
     /**
      * 透明覆盖层的隐藏
      *
      * @return 无返回值
      */
     hide: function() {
         if (!this._map) {
             return;
         }
         this._inUse = false;
         if (this._maskElement) {
             this._maskElement.style.display = 'none';
         }
     },
 
     /**
      * 获取HTML容器
      *
      * @param {Map} map map对象
      * @return HTML容器元素
      */
     getDom: function(map) {
         if (!this._maskElement) {
             this._createMask(map);
         }
         return this._maskElement;
     },
 
     /**
      * 设置鼠标样式
      *
      * @type {String} cursor 鼠标样式
      * @return 无返回值
      */
     _setCursor: function(cursor) {
         this._cursor = cursor || 'default';
         if (this._maskElement) {
             this._maskElement.style.cursor = this._cursor;
         }
     }
 };
 
     /**
      * 停止事件冒泡传播，
      * 闭包，对外不暴露
      *
      * @type {Event} e e对象
      */
     function stopBubble(e) {
         var e = window.event || e;
         e.stopPropagation ? e.stopPropagation() : (e.cancelBubble = true);
             }
    })();